import { ref, type Ref } from "vue";
export class AliyunASR {
  private isRecording = ref<boolean>(false);
  private isConnecting = ref<boolean>(false);
  private transcriptionResult = ref<string>("");
  private ws: WebSocket | null = null;
  private reconnectTimer: ReturnType<typeof setTimeout> | null = null;
  private audioContext: AudioContext | null = null;
  private mediaStream: MediaStream | null = null;
  private streamSource: MediaStreamAudioSourceNode | null = null;
  private scriptProcessor: ScriptProcessorNode | null = null;

  // 建立 WebSocket 连接
  private async initWebSocket(): Promise<boolean> {
    if (this.ws) {
      // 清理现有连接
      this.ws.onopen = null;
      this.ws.onclose = null;
      this.ws.onerror = null;
      this.ws.onmessage = null;

      try {
        if (
          this.ws.readyState === WebSocket.OPEN ||
          this.ws.readyState === WebSocket.CONNECTING
        ) {
          this.ws.close();
        }
      } catch (e) {
        console.error("关闭WebSocket时出错:", e);
      }
      this.ws = null;
    }

    this.isConnecting.value = true;

    try {
      this.ws = new WebSocket(
        `${import.meta.env.VITE_WS_TYPE}://${
          import.meta.env.VITE_DEVELOPMENT_URL
        }/api/ws/asr`
      );

      return new Promise<boolean>((resolve) => {
        if (!this.ws) {
          this.isConnecting.value = false;
          resolve(false);
          return;
        }

        // 设置超时
        const timeoutId = setTimeout(() => {
          console.error("WebSocket连接超时");
          this.isConnecting.value = false;
          resolve(false);
        }, 10000);

        this.ws.onopen = () => {
          clearTimeout(timeoutId);
          // console.log("WebSocket 连接成功");
          this.isConnecting.value = false;
          resolve(true);
        };

        this.ws.onclose = () => {
          clearTimeout(timeoutId);
          if (this.isRecording.value) {
            // console.log("WebSocket 连接关闭:", event.code, event.reason);
            this.scheduleReconnect();
          }
          this.isConnecting.value = false;
          resolve(false);
        };

        this.ws.onerror = (error) => {
          clearTimeout(timeoutId);
          console.error("WebSocket 错误:", error);
          this.isConnecting.value = false;
          resolve(false);
        };

        this.ws.onmessage = (event) => {
          const data = event.data;
          if (typeof data === "string") {
            if (data == "asr stopped") {
              // ws.close();
            } else {
              const jsonData = JSON.parse(data);
              if (jsonData.text) {
                this.transcriptionResult.value = jsonData.text;
              }
            }
          }
        };
      });
    } catch (error) {
      console.error("WebSocket 连接初始化失败:", error);
      this.isConnecting.value = false;
      return false;
    }
  }

  // 安排重连
  private async scheduleReconnect(): Promise<void> {
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer);
    }

    if (!this.isRecording.value) {
      return; // 如果不在录音中，不需要重连
    }

    await this.initWebSocket();
  }

  // 开始录音并直接以PCM格式发送
  public async startRecording(): Promise<void> {
    if (this.isRecording.value) return; // 防止重复启动
    console.log("开始录音");
    // 先连接 WebSocket
    const connected = await this.initWebSocket();
    if (!connected) {
      console.error("无法连接 WebSocket，无法开始录音");
      return;
    }

    try {
      // 获取麦克风权限
      this.mediaStream = await navigator.mediaDevices.getUserMedia({
        audio: {
          sampleRate: 16000,
          channelCount: 1,
          echoCancellation: true,
          noiseSuppression: true,
        },
      });

      // 创建音频上下文（指定采样率为16000）
      this.audioContext = new (window.AudioContext ||
        (window as any).webkitAudioContext)({
        sampleRate: 16000,
      });

      // 创建源节点
      this.streamSource = this.audioContext.createMediaStreamSource(
        this.mediaStream
      );

      // 创建处理节点（8192缓冲区大小，单声道输入和输出）
      this.scriptProcessor = this.audioContext.createScriptProcessor(
        8192,
        1,
        1
      );

      // 处理音频数据
      this.scriptProcessor.onaudioprocess = (e) => {
        if (
          !this.isRecording.value ||
          !this.ws ||
          this.ws.readyState !== WebSocket.OPEN
        )
          return;

        // 获取输入数据
        const inputData = e.inputBuffer.getChannelData(0);

        // 直接发送音频数据到服务器
        if (this.ws.readyState === WebSocket.OPEN) {
          this.ws.send(inputData.buffer);
        }
      };

      // 连接节点
      this.streamSource.connect(this.scriptProcessor);
      this.scriptProcessor.connect(this.audioContext.destination);

      this.isRecording.value = true;
    } catch (error) {
      console.error("开始录音失败:", error);
    }
  }

  // 停止录音
  public stopRecording(): void {
    console.log("停止录音");

    this.isRecording.value = false;

    // 停止音频处理
    if (this.scriptProcessor) {
      this.scriptProcessor.disconnect();
      this.scriptProcessor = null;
    }

    if (this.streamSource) {
      this.streamSource.disconnect();
      this.streamSource = null;
    }

    // 关闭音频上下文
    if (this.audioContext) {
      this.audioContext
        .close()
        .catch((err) => console.error("关闭音频上下文失败:", err));
      this.audioContext = null;
    }

    // 释放媒体流
    if (this.mediaStream) {
      this.mediaStream.getTracks().forEach((track) => track.stop());
      this.mediaStream = null;
    }

    // 发送结束命令（如果WebSocket连接可用）
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      // 关闭 WebSocket 连接
      this.ws.close();
      this.ws = null;
    }

    // 清除重连定时器
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer);
      this.reconnectTimer = null;
    }
  }

  public getTranscriptionResult(): Ref<string> {
    return this.transcriptionResult;
  }
}

// 创建和导出默认实例
export default new AliyunASR();
